package game.core
{
	import away3d.animators.*;
	import engine.core.*;
	import engine.graphics.*;
	import engine.graphics.resources.*;
	import engine.profile.*;
	import flash.display.*;
	import flash.geom.*;
	import flash.system.*;
	import game.graphics.away3d.*;
	
	public class RxProfilerState
	{
		private var m_stage:Stage;
		private var m_state:uint;
		private var m_updateCount:uint;
		private var m_appMemory:Number;
		private var m_appMemoryUpdateFrames:uint;
		
		public static const PROFILE_FRAME:uint = 1;
		public static const PROFILE_FRAME_MIN:uint = 2;
		public static const PROFILE_ACCUM:uint = 3;
		public static const PROFILE_SAMPLING:uint = 4;
		
		private var m_frameDualProfiler:RxDualProfiler;
		private var m_accumDualProfiler:RxDualProfiler;
		private var m_samplingProfiler:RxSamplingProfiler;
		private var m_minTimingProfileData:RxTimingProfileData;
		
		public function RxProfilerState(stage:Stage, style:String)
		{
			m_stage = stage;
			
			if (style == null)
			{
				style = "Courier";
			}
			
			m_frameDualProfiler = new RxDualProfiler(style);
			m_accumDualProfiler = new RxDualProfiler(style);
			m_samplingProfiler = new RxSamplingProfiler();
			m_samplingProfiler.SampleInternalAllocs(false);
			m_samplingProfiler.TrackAllocs(false);
			m_minTimingProfileData = new RxTimingProfileData();
			
			var frameTimingProfiler:RxTimingProfiler = m_frameDualProfiler.GetTimingProfiler();
			var frameMemoryProfiler:RxMemoryProfiler = m_frameDualProfiler.GetMemoryProfiler();
			var accumTimingProfiler:RxTimingProfiler = m_accumDualProfiler.GetTimingProfiler();
			var accumMemoryProfiler:RxMemoryProfiler = m_accumDualProfiler.GetMemoryProfiler();
			
			frameTimingProfiler.GetTextField().SetColors(16777215, 0, 8421504, 0.8);
			frameMemoryProfiler.GetTextField().SetColors(16777215, 0, 8421504, 0.8);
			accumTimingProfiler.GetTextField().SetColors(16777215, 0, 8421504, 0.8);
			accumMemoryProfiler.GetTextField().SetColors(16777215, 0, 8421504, 0.8);
			
			m_frameDualProfiler.GetTimingProfiler().Enable(false);
			m_frameDualProfiler.GetMemoryProfiler().Enable(false);
			m_accumDualProfiler.GetTimingProfiler().Enable(true);
			m_accumDualProfiler.GetMemoryProfiler().Enable(true);
			
			//this.SetState(0, null);
			this.SetState(PROFILE_FRAME, null);
			
			this.m_updateCount = 0;
			this.m_appMemory = System.privateMemory;
			this.m_appMemoryUpdateFrames = 30;
			this.m_minTimingProfileData.Start("min", 0);
		}
		
		public function SetState(state:uint, frame:Object) : void
		{
			var curFrame:uint = 0;
			this.m_state = state;
			var frameIsChildOfStage:Boolean = this.m_frameDualProfiler.GetTimingProfiler().IsChildOfStage(this.m_stage);
			var accumIsChildOfStage:Boolean = this.m_accumDualProfiler.GetTimingProfiler().IsChildOfStage(this.m_stage);
			if (this.m_state == 0)
			{
				this.m_frameDualProfiler.GetTimingProfiler().Enable(false);
				this.m_frameDualProfiler.GetMemoryProfiler().Enable(false);
				if (frameIsChildOfStage)
				{
					this.m_frameDualProfiler.RemoveFromStage(this.m_stage);
				}
				if (accumIsChildOfStage)
				{
					this.m_accumDualProfiler.RemoveFromStage(this.m_stage);
				}
			}
			else if (this.m_state == PROFILE_FRAME)
			{
				this.m_frameDualProfiler.GetTimingProfiler().Enable(true);
				this.m_frameDualProfiler.GetMemoryProfiler().Enable(true);
				if (!frameIsChildOfStage)
				{
					this.m_frameDualProfiler.AddToStage(this.m_stage);
				}
				if (accumIsChildOfStage)
				{
					this.m_accumDualProfiler.RemoveFromStage(this.m_stage);
				}
			}
			else if (this.m_state == PROFILE_FRAME_MIN)
			{
				this.m_frameDualProfiler.GetTimingProfiler().Enable(false);
				this.m_frameDualProfiler.GetMemoryProfiler().Enable(false);
				if (!frameIsChildOfStage)
				{
					this.m_frameDualProfiler.AddToStage(this.m_stage);
				}
				if (accumIsChildOfStage)
				{
					this.m_accumDualProfiler.RemoveFromStage(this.m_stage);
				}
			}
			else if (this.m_state == PROFILE_ACCUM)
			{
				this.m_frameDualProfiler.GetTimingProfiler().Enable(false);
				this.m_frameDualProfiler.GetMemoryProfiler().Enable(false);
				if (frameIsChildOfStage)
				{
					this.m_frameDualProfiler.RemoveFromStage(this.m_stage);
				}
				if (!accumIsChildOfStage)
				{
					this.m_accumDualProfiler.AddToStage(this.m_stage);
				}
			}
			else if (this.m_state == PROFILE_SAMPLING)
			{
				this.m_frameDualProfiler.GetTimingProfiler().Enable(false);
				this.m_frameDualProfiler.GetMemoryProfiler().Enable(false);
				if (frameIsChildOfStage)
				{
					this.m_frameDualProfiler.RemoveFromStage(this.m_stage);
				}
				if (accumIsChildOfStage)
				{
					this.m_accumDualProfiler.RemoveFromStage(this.m_stage);
				}
				curFrame = uint(frame);
				if (this.m_samplingProfiler.CaptureFrames(curFrame))
				{
					this.m_samplingProfiler.ProcessSampleTypes(false, true);
					this.m_samplingProfiler.TrackAllocs(true);
				}
			}
			
			if (this.m_state == PROFILE_FRAME_MIN)
			{
				this.m_frameDualProfiler.GetTimingProfiler().GetTextField().SetRect(new Rectangle(0, 0, 180, 20));
				this.m_frameDualProfiler.GetMemoryProfiler().GetTextField().SetRect(new Rectangle(180, 0, 260, 20));
				this.m_accumDualProfiler.GetTimingProfiler().GetTextField().SetRect(new Rectangle(0, 0, 180, 20));
				this.m_accumDualProfiler.GetMemoryProfiler().GetTextField().SetRect(new Rectangle(180, 0, 260, 20));
			}
			else
			{
				this.m_frameDualProfiler.GetTimingProfiler().GetTextField().SetRect(new Rectangle(0, 0, 300, 280));
				this.m_frameDualProfiler.GetMemoryProfiler().GetTextField().SetRect(new Rectangle(300, 0, 420, 280));
				this.m_accumDualProfiler.GetTimingProfiler().GetTextField().SetRect(new Rectangle(0, 0, 300, 280));
				this.m_accumDualProfiler.GetMemoryProfiler().GetTextField().SetRect(new Rectangle(300, 0, 420, 280));
			}
		}
		
		public function GetSamplingProfiler() : RxSamplingProfiler
		{
			return this.m_samplingProfiler;
		}
		
		public function GetFrameDualProfiler() : RxDualProfiler
		{
			return this.m_frameDualProfiler;
		}
		
		public function GetAccumDualProfiler() : RxDualProfiler
		{
			return this.m_accumDualProfiler;
		}
		
		public function UpdateTextFields(param1:RxRenderer, param2:RxScene) : void
		{
			var _loc_3:uint = 0;
			var _loc_4:String = null;
			var _loc_5:Number = NaN;
			var _loc_6:Number = NaN;
			var _loc_7:Number = NaN;
			var _loc_8:Number = NaN;
			var _loc_9:RxTimingProfiler = null;
			var _loc_10:RxMemoryProfiler = null;
			var _loc_11:RxTimingProfileData = null;
			var _loc_12:RxTimerWorker = null;
			var _loc_13:uint = 0;
			var _loc_14:Number = NaN;
			var _loc_15:Number = NaN;
			var _loc_16:Vector.<RxGPUResource> = null;
			if (this.m_state == 0)
			{
				return;
			}
			if (this.m_state == PROFILE_SAMPLING)
			{
				_loc_3 = this.m_samplingProfiler.Update();
				if (_loc_3)
				{
					RxLog.Info("\n********************************");
					RxLog.Info("**** sampler captured " + _loc_3 + " frames\n");
					_loc_4 = this.m_samplingProfiler.DumpTimingStats();
					RxLog.Info("**** timing sampling:\n" + _loc_4);
					_loc_4 = this.m_samplingProfiler.DumpMemoryStats();
					RxLog.Info("**** memory sampling:\n" + _loc_4);
					_loc_4 = this.m_samplingProfiler.DumpTrackedAllocs();
					RxLog.Info("**** tracked allocs:\n" + _loc_4);
					RxLog.Info("********************************\n");
				}
			}
			else
			{
				_loc_9 = this.m_frameDualProfiler.GetTimingProfiler();
				_loc_10 = this.m_frameDualProfiler.GetMemoryProfiler();
				if (this.m_state == PROFILE_FRAME)
				{
					this.m_updateCount = this.m_updateCount + 1;
					if (this.m_updateCount % this.m_appMemoryUpdateFrames == 0)
					{
						this.m_appMemory = System.privateMemory;
					}
					_loc_11 = RxTimingProfileData(_loc_9.GetProfileData(0));
					_loc_5 = _loc_11.GetAverage();
					_loc_6 = 1000 / _loc_5;
					_loc_7 = System.freeMemory;
					_loc_8 = System.totalMemoryNumber;
					this.m_frameDualProfiler.ClearTextField();
					_loc_9.GetTextField().AddText("fps: " + _loc_6.toFixed(1) + "\n\n");
					_loc_10.GetTextField().AddText("total: " + RxUtilities.scvt(_loc_8, 1) + ", free: " + RxUtilities.scvt(_loc_7, 1) + ", app: " + RxUtilities.scvt(this.m_appMemory, 1) + "\n\n");
					this.m_frameDualProfiler.UpdateTextField("timing:\n", "memory:\n", false, true, 1);
					_loc_9.GetTextField().AddText("\nmodels: " + param2.GetNumModels() + ", anim: " + AnimatorBase.s_numAnimators + "\n");
					_loc_12 = param1.GetWorker();
					_loc_13 = _loc_12.GetTotalTicks();
					_loc_14 = _loc_12.GetTotalTime();
					_loc_15 = _loc_14 / Number(_loc_13);
					_loc_9.GetTextField().AddText("worker: " + _loc_13 + ", " + _loc_14.toFixed(0) + " ms (avg: " + _loc_15.toFixed(2) + " ms)\n");
					_loc_16 = RxGPUResource.GetAllResources();
					_loc_10.GetTextField().AddText("\nresources: " + _loc_16.length + "\n");
				}
				else if (this.m_state == PROFILE_FRAME_MIN)
				{
					this.m_minTimingProfileData.End();
					_loc_5 = this.m_minTimingProfileData.GetAverage();
					_loc_6 = 1000 / _loc_5;
					this.m_minTimingProfileData.Start("min", 0);
					_loc_7 = System.freeMemory;
					_loc_8 = System.totalMemoryNumber;
					this.m_frameDualProfiler.ClearTextField();
					_loc_9.GetTextField().AddText("fps: " + _loc_6.toFixed(1) + " (" + _loc_5.toFixed(1) + " ms)");
					_loc_10.GetTextField().AddText("total: " + RxUtilities.scvt(_loc_8, 1) + ", free: " + RxUtilities.scvt(_loc_7, 1));
				}
				else if (this.m_state == PROFILE_ACCUM)
				{
					this.m_accumDualProfiler.UpdateTextField(null, null, true, false, 1);
				}
			}
		}
	}
}